package earth;
import hla.rti.AttributeHandleSet;
import hla.rti.LogicalTime;
import hla.rti.LogicalTimeInterval;
import hla.rti.RTIambassador;
import hla.rti.RTIexception;
import hla.rti.RTIinternalError;
import hla.rti.ResignAction;
import hla.rti.jlc.RtiFactoryFactory;
import org.portico.impl.hla13.types.DoubleTime;
import org.portico.impl.hla13.types.DoubleTimeInterval;
import core.Parachute;
import core.Plane;
public class GEManager {
private RTIambassador rtiAmbassador = null;
private GEAmbassador earthAmbassador = null;
private Plane plane = new Plane();
private Parachute parachute = new Parachute();
int flightGearHandle;
int fgAltitudeHandle;
int fgLatitudeHandle;
int fgLongitudeHandle;
int fgVelocityHandle;
int parachuteHandle;
int pStatusHandle;
int pAltitudeHandle;
int pLatitudeHandle;
int pLongitudeHandle;
public GEManager() {
try {
rtiAmbassador = RtiFactoryFactory.getRtiFactory().createRtiAmbassador();
} catch (RTIinternalError e) {
e.printStackTrace();
}
}
/** The sync point all federates will sync up on before starting */
public static final String READY_TO_RUN = "ReadyToRun";
public void runFederate(String federateName) throws RTIexception {
earthAmbassador = new GEAmbassador(this, plane, parachute);
rtiAmbassador.joinFederationExecution(federateName, "FlightGearSimulation", earthAmbassador);
enableTimePolicy();
subscribe();
startServer();
boolean planeFlies = true;
while(planeFlies) {
rtiAmbassador.tick();
advanceTime();
}
rtiAmbassador.resignFederationExecution(ResignAction.NO_ACTION);
}
private void startServer() {
Runnable r = new Runnable() {
@Override
public void run() {
new GEServer(plane, parachute).startServer();
}
};
new Thread(r).start();
}
/**
* This method will request a time advance to the current time, plus the given
* timestep. It will then wait until a notification of the time advance grant
* has been received.
*/
private void advanceTime() throws RTIexception {
// request the advance
earthAmbassador.setAdvancing(true);
LogicalTime newTime = convertTime(earthAmbassador.getFederateTime() + 1.0);
rtiAmbassador.timeAdvanceRequest(newTime);
// wait for the time advance to be granted. ticking will tell the
// LRC to start delivering callbacks to the federate
while(earthAmbassador.isAdvancing()) {
rtiAmbassador.tick();
}
}
private void enableTimePolicy() throws RTIexception {
// ///////////////////////////
// enable time constrained //
// ///////////////////////////
rtiAmbassador.enableTimeConstrained();
// tick until we get the callback
while (!earthAmbassador.isConstrained()) {
rtiAmbassador.tick();
}
}
/**
*/
private void subscribe() throws RTIexception {
flightGearHandle = rtiAmbassador.getObjectClassHandle("HLAobjectRoot.FlightGear");
fgAltitudeHandle = rtiAmbassador.getAttributeHandle("Altitude", flightGearHandle);
fgLatitudeHandle = rtiAmbassador.getAttributeHandle("Latitude", flightGearHandle);
fgLongitudeHandle = rtiAmbassador.getAttributeHandle("Longitude", flightGearHandle);
AttributeHandleSet attributes = RtiFactoryFactory.getRtiFactory().createAttributeHandleSet();
attributes.add(fgAltitudeHandle);
attributes.add(fgLatitudeHandle);
attributes.add(fgLongitudeHandle);
rtiAmbassador.subscribeObjectClassAttributes(flightGearHandle, attributes);
parachuteHandle = rtiAmbassador.getObjectClassHandle("HLAobjectRoot.Parachute");
pStatusHandle = rtiAmbassador.getAttributeHandle("Status", parachuteHandle);
pAltitudeHandle = rtiAmbassador.getAttributeHandle("Altitude", parachuteHandle);
pLatitudeHandle = rtiAmbassador.getAttributeHandle("Latitude", parachuteHandle);
pLongitudeHandle = rtiAmbassador.getAttributeHandle("Longitude", parachuteHandle);
attributes = RtiFactoryFactory.getRtiFactory().createAttributeHandleSet();
attributes.add(pStatusHandle);
attributes.add(pAltitudeHandle);
attributes.add(pLatitudeHandle);
attributes.add(pLongitudeHandle);
rtiAmbassador.subscribeObjectClassAttributes(parachuteHandle, attributes);
}
/**
*
* @param args
*/
public static void main(String[] args) {
final GEManager earthManager = new GEManager();
Runnable r = new Runnable() {
@Override
public void run() {
try {
earthManager.runFederate("GoogleEarth");
} catch (RTIexception e) {
e.printStackTrace();
}
}
};
new Thread(r).start();
}
/**
* As all time-related code is Portico-specific, we have isolated it into a
* single method. This way, if you need to move to a different RTI, you only need
* to change this code, rather than more code throughout the whole class.
*/
private LogicalTime convertTime( double time )
{
// PORTICO SPECIFIC!!
return new DoubleTime( time );
}
/**
* Same as for {@link #convertTime(double)}
*/
private LogicalTimeInterval convertInterval( double time )
{
// PORTICO SPECIFIC!!
return new DoubleTimeInterval( time );
}
}